STM32与MQTT(一)STM32+ESP8266连接TCP服务器

您所在的位置:网站首页 esp8266 mesh不稳定 STM32与MQTT(一)STM32+ESP8266连接TCP服务器

STM32与MQTT(一)STM32+ESP8266连接TCP服务器

2023-10-22 04:49| 来源: 网络整理| 查看: 265

STM32与MQTT(一)STM32+ESP8266连接TCP服务器 0. 前言1. 开发前准备1.1 准备工作1.2 说明 2. 开发过程2.1 USART1与USART2串口使用2.1.1 两个串口使用上的区别2.1.2 工程配置2.1.3 修改 "usart.h"2.1.4 修改 "usart.c"2.1.5 修改 "stm32f1xx_it.c"2.1.6 设置监听2.1.7 测试代码 2.2 连接STM32与ESP82662.2.1 熟悉AT指令2.2.2 串口驱动ESP8266连接电脑TCP服务器2.2.3 STM32驱动ESP8266连接电脑TCP服务器 3. 结束

0. 前言

本系列不讲MQTT协议具体的原理,只说怎么使用STM32+ESP8266在裸机状态下使用HAL库连接华为云MQTT服务器

1. 开发前准备 1.1 准备工作 STM32F103C8T6核心板正点原子ATK-ESP-01模块(也可以使用其他ESP8266模块)开发环境:STM32CubeIDE串口调试助手参考作者 张竞豪 的文章,写的真的很好 1.2 说明 使用资源说明 使用资源功能USART1DBG信息打印USART2连接ESP8266模块进行配置与网络通信DMA1_Channel6USART2_Rx的DMA用作与接收数据PB15ESP8266模块复位引脚PC13板载LED灯 正点原子ATK-ESP-01模块使用请下载资料,就算使用其他的ESP8266模块也可使用正点原子的资料,主要参考资料中对于ESP8266的AT指令集的说明。使用STM32CubeIDE开发,集成环境,个人觉得在STM32开发上比MDK环境好用使用野火的fireTool,网络调试,串口调试一应俱全虽然我没有私信联系这位作者,但是我很感谢他,基本上是跟着他文章做下来的 2. 开发过程 2.1 USART1与USART2串口使用 2.1.1 两个串口使用上的区别

请耐心看完以下内容 使用USART1时,考虑到在设计中只用作DBG信息打印,因此对其接收没有要求,甚至不需要接收,在这里我没有用到USART1的接收功能 使用USART2时,首先要搞清楚,USART2是如何通过ESP8266连接网络,并进行通信的。类比HC-05等的蓝牙模块,这类模块通过串口线连接到串口上,配置并连接完成后,对下层透明,下层不需要关心协议如何实现,只对其连接的串口发送信息,而将信息加上头部、解包或无线传输等功能完全由该芯片(模块)实现。所以类比HC-05等蓝牙模块,我们对ESP8266模块要做的事情非常简单:正确配置,连接网络,使能发送。 由于USART2需要发送与接收数据,显然,发送数据的长度是本地可控的,简单使用HAL库函数即可完成,但是接收数据的长度是不可控的,其完全由配置过程中ESP8266返回的数据和配置完成后ESP8266接收到的数据长度指定,即接收到的数据是不定长的,为了实现不定长实时数据接收,在这里我们使用DMA+中断的方法(参考文章找不到了,但是能搜到的方法大致相同,我也会贴出我用到的方法)。

2.1.2 工程配置

使用资源一览,时钟树使用外部晶振,直接拉满就可以 配置图1 DMA1_Channel6 配置直接使用默认的就可以 配置图2 让STM32CubeIDE内置的CubeMX在生成代码时按照库的方式来生成 配置图3 扩大栈堆 配置图4

2.1.3 修改 “usart.h”

打开生成后的工程中usart.h 在usart.h中加入需要用到的变量

/* 对照注释提示插入代码,不在注释包括出来的 * 区域内的代码在重新生成代码时会被清除 */ /* USER CODE BEGIN Private defines */ // 用户代码开始 #define USART1_MAX_SENDLEN 1024 #define USART1_MAX_RECVLEN 1024 #define USART2_MAX_SENDLEN 1024 #define USART2_MAX_RECVLEN 1024 // 用户代码结束 /* USER CODE END Private defines */ void MX_USART1_UART_Init(void); // CubeMX生成的代码 void MX_USART2_UART_Init(void); // CubeMX生成的代码 /* USER CODE BEGIN Prototypes */ // 用户代码开始 extern uint8_t USART1_TxBUF[USART1_MAX_SENDLEN];// usart1 发送数据缓存区 extern uint8_t USART1_RxBUF[USART1_MAX_RECVLEN];// usart1 接收数据缓存区 extern uint8_t USART2_TxBUF[USART2_MAX_SENDLEN];// usart2 发送数据缓存区 extern uint8_t USART2_RxBUF[USART2_MAX_RECVLEN];// usart2 接收数据缓存区 extern volatile uint8_t USART2_RxLen;// usart2 接收数据长度 extern volatile uint8_t USART2_RecvEndFlag;// usart2 接收数据完成标志位 // 对usart1发送数据 void u1_printf(char *fmt, ...); // 我不喜欢将对usart2发送数据也命名为printf,因为实际上并没有对我print void u2_transmit(char *fmt, ...); // 用户代码结束 /* USER CODE END Prototypes */ 2.1.4 修改 “usart.c”

在 MX_USART2_UART_Init(void) 函数中添加以下代码,开启IDLE中断,并使能DMA接收 在最后添加第2步中声明的两个函数的函数体

void MX_USART2_UART_Init(void) { //...... /* USER CODE BEGIN USART2_Init 2 */ __HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE); HAL_UART_Receive_DMA(&huart2, USART2_RxBUF, USART2_MAX_RECVLEN); /* USER CODE END USART2_Init 2 */ //...... } /**********************分割线**********************/ /* USER CODE BEGIN 1 */ // 用户代码开始 void u1_printf(char *fmt, ...) { uint16_t i; va_list ap; va_start(ap, fmt); vsprintf((char*) USART1_TxBUF, fmt, ap); va_end(ap); i = strlen((const char*) USART1_TxBUF); HAL_UART_Transmit(&huart1, USART1_TxBUF, i, 100); memset(USART1_TxBUF, 0, USART1_MAX_SENDLEN); } void u2_transmit(char *fmt, ...) { uint16_t i, j; va_list ap; va_start(ap, fmt); vsprintf((char*) USART2_TxBUF, fmt, ap); va_end(ap); // 排除掉发送信息中所有的'\00'使有效信息可以发送 // 但是仍要考虑到,MQTT报文等内容中可能含有'\00' // 这个时候就需要直接使用HAL_UART_Transmit()函数发送 // 而放弃使用u2_transmit() for (i = 0; i for (; j /* USER CODE BEGIN USART2_IRQn 0 */ uint32_t tmp_flag = 0; uint32_t temp; tmp_flag = __HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE); if ((tmp_flag != RESET)) { __HAL_UART_CLEAR_IDLEFLAG(&huart2); temp = huart2.Instance->SR; temp = huart2.Instance->DR; HAL_UART_DMAStop(&huart2); temp = hdma_usart2_rx.Instance->CNDTR; USART2_RxLen = USART2_MAX_RECVLEN - temp; USART2_RecvEndFlag = 1; } /* USER CODE END USART2_IRQn 0 */ HAL_UART_IRQHandler(&huart2); /* USER CODE BEGIN USART2_IRQn 1 */ /* USER CODE END USART2_IRQn 1 */ } 2.1.6 设置监听

完成上述步骤后,如果需要获取USART2接收到的数据只需要在需要获取数据的位置监听 USART2_RecvEndFlag 的值,当其为1时,读取USART2_RxBUF的内容即可,示例:

/* 在timeout时间内进行监听, * 如果监听到USART2_RecvEndFlag为1则对数据进行处理 */ while (timeout--) { // u1_printf("%d ", timeout); // finish dma receive if (USART2_RecvEndFlag == 1) { check = esp8266_CheckRespond(ack); if (check == _MATCHOK) { u1_printf("(DBG:) Command closed loop completed\r\n"); } USART2_RxLen = 0; USART2_RecvEndFlag = 0; HAL_UART_Receive_DMA(&huart2, USART2_RxBUF, USART2_MAX_RECVLEN); break; } HAL_Delay(1); } 2.1.7 测试代码

不做展开,请自己测试一下,如果不成功,请搜索相关内容再次尝试,只要usart2能够实现不定长数据接收,就可开始下一步

2.2 连接STM32与ESP8266 2.2.1 熟悉AT指令

请耐心看完以下内容 如果你已经下载了正点原子的资料,那么可以打开6,ESP8266相关资料文件夹,查阅ESP8266_AT指令集V2.1.0了解ESP8266的AT指令集,在实际连接前,可以先使用CH340x、CP2102等串口模块通过串口调试助手将ESP8266模块连接到网络,熟悉这个过程后,只需要使用STM32的USART2向ESP8266模块发送在串口助手中发送过的指令,就可以使用STM32驱动ESP8266连接网络 那么先来了解一下本次需要用到的AT指令,均来自ESP8266_AT指令集V2.1.0

AT指令作用+++请参照说明文档AT\r\nAT测试指令,返回OKATEx\r\nx:0—关闭回显,1—打开回显AT+CWMODE_CUR=x\r\n设置模块工作模式,不保存到Flash,x:0—AP,1—STA,2—AP+STAAT+CWAUTOCONN=x\r\n设置自动连接,x:0—关闭,1—开启AT+CWJAP_CUR=“ssid”,“pswd”\r\n连接AP网络,不保存到Flash,ssid—网络名称,pswd—密码AT+CWJAP_CUR?\r\n查询网络信息,需要连接到网络AT+CIPSTA_CUR?\r\n查询IP信息,需要连接到网络AT+CWDHCP_CUR=x,y\r\n请参照说明文档AT+CIPMUX=x\r\n多连接模式设置,x:0—关闭,1—开启AT+CIPMODE=x\r\n传输模式设置,x:0—普通模式,1—透传模式AT+CIPSTART=“mode”,“IpServer”,ServerPort\r\n连接到服务器,具体请参照说明文档,mode指示服务器类型,IpServer指示服务器地址,ServerPort指示服务器端口AT+CIPSEND\r\n发送数据

其他AT指令请查阅文档,将以上步骤按照设定参数并需要执行一次后,向ESP8266发送数据,TCP服务端即可收到数据。

2.2.2 串口驱动ESP8266连接电脑TCP服务器

接收数据测试,以连接WIFI上网的Windows电脑为例:

在命令行中使用ipconfig查找到本机的ip地址 在这里插入图片描述在串口调试助手中设置 在这里插入图片描述 端口使用默认端口即可,注意这两个对应上述指令中的AT+CIPSTART=“mode”,“IpServer”,“ServerPort”,将mode设置为TCP,因为连接的是TCP服务器使用USB转串口模块连接电脑与ESP8266模块,在串口中向ESP8266模块发送下图所示指令,得到返回结果,注意在发送服务器信息时,端口号不加引号,最后进行发送信息测试 发送指令并得到返回发送测试信息 接收到信息 2.2.3 STM32驱动ESP8266连接电脑TCP服务器 创建 “esp8266.h” 和 “esp8266.c” 文件检查AT指令返回的数据 使用函数strstr(str1, str2) 具体原理不赘述,该函数如果查找成功则返回值不为NULL。使用此方法可以检查发送AT指令后得到的返回结果是否为预期,由此来判断AT指令是否成功发送以及是否起作用 // WIFI_StateTypeDef 是我自己定义的一个表示ESP8266状态的enum类型 // str 为期望的返回,如期望返回 "OK",则str应设置为 "OK" WIFI_StateTypeDef esp8266_CheckRespond(uint8_t *str) { u1_printf("(DBG:) usart2 recv:\r\n%s\r\n", USART2_RxBUF); if (strstr((const char*) USART2_RxBUF, (const char*) str) != NULL) { u1_printf("(DBG:) Match succeed\r\n"); memset(USART2_RxBUF, 0, USART2_MAX_RECVLEN); return _MATCHOK; } memset(USART2_RxBUF, 0, USART2_MAX_RECVLEN); return _MATCHERROR; } 发送AT指令并检查指令闭环 /** * @param cmd: cmd to be send * @param ack: correct ack to be checked * @param waitms: wait time ms * @param newline: transmit a new line or not */ WIFI_StateTypeDef esp8266_TransmitCmd(uint8_t *cmd, uint8_t *ack, uint32_t waitms, uint8_t newline) { int timeout = waitms; uint8_t check = 0; memset(USART2_RxBUF, 0, USART2_MAX_RECVLEN); u1_printf("\r\n(DBG:) Try to send cmd: %s\r\n", cmd); if (newline == 0) u2_transmit("%s", cmd); // transmit cmd to usart2 else u2_transmit("%s\r\n", cmd); // transmit cmd to usart2 u1_printf("(DBG:) Waiting reply\r\n"); while (timeout--) { // u1_printf("%d ", timeout); // finish dma receive if (USART2_RecvEndFlag == 1) { check = esp8266_CheckRespond(ack); if (check == _MATCHOK) { u1_printf("(DBG:) Command closed loop completed\r\n"); } USART2_RxLen = 0; USART2_RecvEndFlag = 0; HAL_UART_Receive_DMA(&huart2, USART2_RxBUF, USART2_MAX_RECVLEN); break; } HAL_Delay(1); } if (check == _MATCHERROR) { u1_printf("\r\n(DBG:) Cmd match failed\r\n"); return check; } if (timeout uint8_t retry_count = 0; /* Other steps */ /**************************分割线**************************/ /* Close echo */ u1_printf("(DBG:) Trying to close echo\r\n"); wifi_config_step++; while (esp8266_TransmitCmd((uint8_t*) "ATE0", OK_ACK, 500, WITH_NEWLINE) != _SUCCEED) { retry_count++; HAL_Delay(1000); if (retry_count > ESP8266_MAX_RETRY_TIME) { u1_printf("(DBG:) Close echo failed\r\n"); retry_count = 0; wifi_config_step--; return _FAILED; } } HAL_Delay(100); retry_count = 0; // reset retry count /**************************分割线**************************/ /* Other steps */ } 测试使用STM32驱动ESP8266连接电脑TCP服务器 在github仓库中找到 “esp8266.c” 和 “net_conf.h” 两个文件,对 “net_conf.h” 中的网络相关属性做配置,或使用其他的方法使函数可以获取TCP服务器的地址和端口,下面是 “net_conf.h” 的内容 #ifndef __NET_CONF_H #define __NET_CONF_H // Please modify those macro definitions to meet needs #define WIFI_TAR 1 #if WIFI_TAR == 0 #define AP_SSID (const char*)"YOUR OWN WIFI SSID" #define AP_PSWD (const char*)"YOUR OWN WIFI PSWD" #elif WIFI_TAR == 1 #define AP_SSID (const char*)"YOUR OWN PC AP SSID" #define AP_PSWD (const char*)"YOUR OWN PC AP PSWD" #endif #define CONNECT_MODE 0 #if CONNECT_MODE == 0 #define IpServer "YOUR OWN MQTT SERVER ADDRESS" #define ServerPort "YOUR OWN MQTT SERVER PORT" #elif CONNECT_MODE == 1 #define IpServer "YOUR OWN PC TCP SERVER ADDRESS" #define ServerPort "YOUR OWN PC TCP SERVER PORT" #endif #define MQTT_DEVICE_ID (uint8_t*)"YOUR OWN MQTT DEVICE ID" #define MQTT_SECRET (uint8_t*)"YOUR OWN MQTT DEVICE SECRET CODE" #define MQTT_CLIENTID "YOUR OWN MQTT DEVICE CLIENTID" #define MQTT_USERNAME "YOUR OWN MQTT DEVICE USERNAME" #define MQTT_PASSWORD "YOUR OWN MQTT DEVICE PASSWORD" #endif 上面所说的工程中只需要esp8266相关文件即可使STM32驱动ESP8266连接TCP服务器,请务必读多读几遍代码,esp8266.c 代码如下,实际上就是使用之前说的两个函数复现使用串口助手发送AT指令的过程,并加入确认部分,请先运行以下代码通过将测试信息发送给电脑TCP服务器成功后,再进行后续内容 #include "esp8266.h" static WIFI_StateTypeDef wifi_state = _OFFLINE; static WIFI_StateTypeDef trans_state = _UNKNOWN_STATE; static uint8_t wifi_config_step = 0; WIFI_StateTypeDef esp8266_CheckRespond(uint8_t *str) { u1_printf("(DBG:) usart2 recv:\r\n%s\r\n", USART2_RxBUF); if (strstr((const char*) USART2_RxBUF, (const char*) str) != NULL) { u1_printf("(DBG:) Match succeed\r\n"); memset(USART2_RxBUF, 0, USART2_MAX_RECVLEN); return _MATCHOK; } memset(USART2_RxBUF, 0, USART2_MAX_RECVLEN); return _MATCHERROR; } WIFI_StateTypeDef esp8266_TransmitCmd(uint8_t *cmd, uint8_t *ack, uint32_t waitms, uint8_t newline) { int timeout = waitms; uint8_t check = 0; memset(USART2_RxBUF, 0, USART2_MAX_RECVLEN); u1_printf("\r\n(DBG:) Try to send cmd: %s\r\n", cmd); if (newline == 0) u2_transmit("%s", cmd); // transmit cmd to usart2 else u2_transmit("%s\r\n", cmd); // transmit cmd to usart2 u1_printf("(DBG:) Waiting reply\r\n"); while (timeout--) { // u1_printf("%d ", timeout); // finish dma receive if (USART2_RecvEndFlag == 1) { check = esp8266_CheckRespond(ack); if (check == _MATCHOK) { u1_printf("(DBG:) Command closed loop completed\r\n"); } USART2_RxLen = 0; USART2_RecvEndFlag = 0; HAL_UART_Receive_DMA(&huart2, USART2_RxBUF, USART2_MAX_RECVLEN); break; } HAL_Delay(1); } if (check == _MATCHERROR) { u1_printf("\r\n(DBG:) Cmd match failed\r\n"); return check; } if (timeout int timeout = waitms; WIFI_RST_Enable(); HAL_Delay(500); WIFI_RST_Disable(); while (timeout--) { if (USART2_RecvEndFlag == 1) { u1_printf("(DBG:) Hardware Reset OK!\r\n"); HAL_Delay(100); USART2_RxLen = 0; USART2_RecvEndFlag = 0; HAL_UART_Receive_DMA(&huart2, USART2_RxBUF, USART2_MAX_RECVLEN); return _SUCCEED; } HAL_Delay(1); } if (timeout uint16_t cmd_len = strlen(AP_SSID) + strlen(AP_PSWD) + 30; uint8_t *cmd = (uint8_t*) malloc(cmd_len * sizeof(uint8_t)); memset(cmd, 0, cmd_len); sprintf((char*) cmd, "AT+CWJAP_CUR=\"%s\",\"%s\"", AP_SSID, AP_PSWD); if (esp8266_TransmitCmd(cmd, (uint8_t*) "WIFI CONNECTED", 3 * ESP8266_MAX_TIMEOUT, WITH_NEWLINE) == _SUCCEED) wifi_state = _ONLINE; else wifi_state = _OFFLINE; return wifi_state; } WIFI_StateTypeDef esp8266_ConnectServer() { uint16_t cmd_len = strlen(IpServer) + strlen(ServerPort) + 30; uint8_t *cmd = (uint8_t*) malloc(cmd_len * sizeof(uint8_t)); memset(cmd, 0, cmd_len); sprintf((char*) cmd, "AT+CIPSTART=\"TCP\",\"%s\",%s", IpServer, ServerPort); if (esp8266_TransmitCmd(cmd, (uint8_t*) "CONNECT", 3 * ESP8266_MAX_TIMEOUT, WITH_NEWLINE) == _SUCCEED) wifi_state = _CONNECTED; else wifi_state = _DISCONNECTED; return wifi_state; } WIFI_StateTypeDef esp8266_SetUpTCPConnection() { uint8_t retry_count = 0; /* Reset esp8266 */ u1_printf("(DBG:) Trying to reset esp8266\r\n"); wifi_config_step++; while (esp8266_HardwareReset(500) != _SUCCEED) { retry_count++; HAL_Delay(1000); if (retry_count > ESP8266_MAX_RETRY_TIME) { u1_printf("(DBG:) Reset failed\r\n"); retry_count = 0; trans_state = _UNKNOWN_STATE; wifi_config_step--; return _FAILED; } } HAL_Delay(2000); // wait 2 seconds retry_count = 0; // reset retry count /* Disable transparent transmission */ u1_printf("(DBG:) Trying to close transparent transmission\r\n"); wifi_config_step++; while (esp8266_TransmitCmd(TRANS_QUIT_CMD, TRANS_QUIT_CMD, ESP8266_MAX_TIMEOUT, WITHOUT_NEWLINE) != _SUCCEED) { retry_count++; HAL_Delay(1500); if (retry_count > ESP8266_MAX_RETRY_TIME) { u1_printf("(DBG:) Close transparent transmission failed\r\n"); retry_count = 0; wifi_config_step--; return _FAILED; } } trans_state = _TRANS_DISABLE; HAL_Delay(1500); retry_count = 0; // reset retry count /* Close echo */ u1_printf("(DBG:) Trying to close echo\r\n"); wifi_config_step++; while (esp8266_TransmitCmd((uint8_t*) "ATE0", OK_ACK, 500, WITH_NEWLINE) != _SUCCEED) { retry_count++; HAL_Delay(1000); if (retry_count > ESP8266_MAX_RETRY_TIME) { u1_printf("(DBG:) Close echo failed\r\n"); retry_count = 0; wifi_config_step--; return _FAILED; } } HAL_Delay(100); retry_count = 0; // reset retry count /* Set wifi mode 0:AP 1:STA 2:AP+STA */ u1_printf("(DBG:) Trying to set Wifi mode\r\n"); wifi_config_step++; while (esp8266_TransmitCmd((uint8_t*) "AT+CWMODE_CUR=1", OK_ACK, 500, WITH_NEWLINE) != _SUCCEED) { retry_count++; HAL_Delay(1000); if (retry_count > ESP8266_MAX_RETRY_TIME) { u1_printf("(DBG:) Set Wifi mode failed\r\n"); retry_count = 0; wifi_config_step--; return _FAILED; } } HAL_Delay(100); retry_count = 0; // reset retry count /* Disable auto connect */ u1_printf("(DBG:) Trying to close auto connect\r\n"); wifi_config_step++; while (esp8266_TransmitCmd((uint8_t*) "AT+CWAUTOCONN=0", OK_ACK, 500, WITH_NEWLINE) != _SUCCEED) { retry_count++; HAL_Delay(1000); if (retry_count > ESP8266_MAX_RETRY_TIME) { u1_printf("(DBG:) Close auto connect failed\r\n"); retry_count = 0; wifi_config_step--; return _FAILED; } } HAL_Delay(100); retry_count = 0; // reset retry count /* Connect to AP(Wifi) */ u1_printf("(DBG:) Trying to connect to AP\r\n"); wifi_config_step++; while (esp8266_ConnectAP() != _ONLINE) { retry_count++; HAL_Delay(1000); if (retry_count > ESP8266_MAX_RETRY_TIME) { u1_printf("(DBG:) Connect to AP failed\r\n"); retry_count = 0; wifi_config_step--; return _FAILED; } } HAL_Delay(1000); retry_count = 0; // reset retry count /* Try to get AP info */ if (wifi_state == _ONLINE) { while (esp8266_TransmitCmd((uint8_t*) "AT+CWJAP_CUR?", OK_ACK, ESP8266_MAX_TIMEOUT, WITH_NEWLINE) != _SUCCEED) { retry_count++; HAL_Delay(1000); if (retry_count > ESP8266_MAX_RETRY_TIME / 2) { u1_printf("(DBG:) Get AP msg failed\r\n"); u1_printf( "(DBG:) Connect server process will not be terminated"); retry_count = 0; wifi_config_step--; break; } } } HAL_Delay(1000); retry_count = 0; // reset retry count /* Try to get IP info */ if (wifi_state == _ONLINE) { while (esp8266_TransmitCmd((uint8_t*) " AT+CIPSTA_CUR?", OK_ACK, ESP8266_MAX_TIMEOUT, WITH_NEWLINE) != _SUCCEED) { retry_count++; HAL_Delay(1000); if (retry_count > ESP8266_MAX_RETRY_TIME / 2) { u1_printf("(DBG:) Get IP info failed\r\n"); u1_printf( "(DBG:) Connect server process will not be terminated"); retry_count = 0; wifi_config_step--; break; } } } HAL_Delay(1000); retry_count = 0; // reset retry count /* Set DHCP */ u1_printf("(DBG:) Trying to set DHCP mode\r\n"); wifi_config_step++; while (esp8266_TransmitCmd((uint8_t*) "AT+CWDHCP_CUR=1,1", OK_ACK, 1000, WITH_NEWLINE) != _SUCCEED) { retry_count++; HAL_Delay(1000); if (retry_count > ESP8266_MAX_RETRY_TIME) { u1_printf("(DBG:) Set DHCP model failed\r\n"); retry_count = 0; wifi_config_step--; return _FAILED; } } HAL_Delay(1000); retry_count = 0; /* Set single connection */ u1_printf("(DBG:) Trying to set single connection\r\n"); wifi_config_step++; while (esp8266_TransmitCmd((uint8_t*) "AT+CIPMUX=0", OK_ACK, 1000, WITH_NEWLINE) != _SUCCEED) { retry_count++; HAL_Delay(1000); if (retry_count > ESP8266_MAX_RETRY_TIME) { u1_printf("(DBG:) Set single connection model failed\r\n"); retry_count = 0; wifi_config_step--; return _FAILED; } } HAL_Delay(1000); retry_count = 0; /* Set transparent transmission */ u1_printf("(DBG:) Trying to set transparent transmission mode\r\n"); wifi_config_step++; while (esp8266_TransmitCmd((uint8_t*) "AT+CIPMODE=1", OK_ACK, 1000, WITH_NEWLINE) != _SUCCEED) { retry_count++; HAL_Delay(1000); if (retry_count > ESP8266_MAX_RETRY_TIME) { u1_printf("(DBG:) Set transparent transmission mode failed\r\n"); retry_count = 0; wifi_config_step--; return _FAILED; } } HAL_Delay(1000); retry_count = 0; /* Connect to TCP server */ u1_printf("(DBG:) Trying to connect TCP server\r\n"); wifi_config_step++; while (esp8266_ConnectServer() != _CONNECTED) { retry_count++; HAL_Delay(1000); if (retry_count > ESP8266_MAX_RETRY_TIME) { u1_printf("(DBG:) Connect TCP server failed\r\n"); retry_count = 0; wifi_config_step--; return _FAILED; } } HAL_Delay(1000); retry_count = 0; /* enable data send(transparent transmission) */ u1_printf("(DBG:) Trying to enable data send\r\n"); wifi_config_step++; while (esp8266_TransmitCmd((uint8_t*) "AT+CIPSEND", OK_ACK, 1000, WITH_NEWLINE) != _SUCCEED) { retry_count++; HAL_Delay(1000); if (retry_count > ESP8266_MAX_RETRY_TIME) { u1_printf("(DBG:) Set transparent transmission mode failed\r\n"); retry_count = 0; wifi_config_step--; return _FAILED; } } trans_state = _TRANS_ENBALE; HAL_Delay(1000); retry_count = 0; /* send test msg */ // u1_printf("Test msg is sending to TCP Server\r\n"); // u2_transmit("This msg means TCP connection has been set up\r\n"); // u1_printf("Test msg has been send to TCP Server\r\n"); return _SUCCEED; } 3. 结束

参考代码,完成上述过程后,STM32可以成功驱动ESP8266连接TCP服务器,连接不同的TCP服务器只需要修改配置中的服务器地址和服务器端口即可。

祝各位身体健康



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3